package com.huawei.codearts.dao;

import com.huawei.codearts.model.Country;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.query.Order;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;
import java.util.Objects;

@Repository
public class CountryDao {

    private final SessionFactory sessionFactory;

    public CountryDao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    // getOne
    public Country getById(int id) {
        try (Session session = sessionFactory.getCurrentSession()) {
            return session.get(Country.class, id);
        } finally {
            System.out.println("--------------------------------");
        }
    }
    // getOne
//    public Country getById(int id) {
//        Session session = sessionFactory.openSession();
//        Country country = session.get(Country.class, id);
//        session.close();
//        return country;
//    }

    public Object getAll(Country country) {
        Session session = sessionFactory.getCurrentSession();
//        Country items = session.find(Country.class, country.getStart());

        Transaction tx = session.beginTransaction();
        // HQL 查询数据：
        List<Country> countryList = session.createQuery("from Country where start = 0", Country.class).setFirstResult(0).setMaxResults(10).list();
        tx.commit();

        session.close();
        return countryList;
    }

    public List<Country> getList(Country country, int page, int pageSize) {
        Session session = sessionFactory.getCurrentSession();

        // 开启事务
        Transaction tx = session.beginTransaction();
        // https://blog.csdn.net/wrongyao/article/details/82938277
        // https://blog.csdn.net/hnzhangjq/article/details/51191723
        // HQL 查询数据：
        // uniqueResult()---返回唯一的结果集
        Country countryItem = session.createQuery("select c from Country c where c.id = :id", Country.class)
                .setParameter("id", 1)
                .uniqueResult();
        System.out.println("countryItem..." + countryItem.toString());

        // 查询对象中的某些个字段（2个以上）
        List<Object[]> lists = session.createQuery("select c.id, c.name from Country c where c.start = :start")
                .setParameter("start", country.getStart())
                .setFirstResult(1)
                .setMaxResults(3)
                .list();
        for (Object[] s : lists) {
            System.out.println("lists..., id=" + s[0] + ", name=" + s[1]);
        }
        // 查询对象中的某些个字段（2个以上）
        List<Map> lists2 = session.createQuery("select new Map(c.id as id, c.name as name) from Country c where c.start = :start order by c.id desc", Map.class)
                .setParameter("start", country.getStart())
                .setFirstResult(1)
                .setMaxResults(3)
                .list();
        for (Map s : lists2) {
            System.out.println("lists2..., id=" + s.get("id")+ ", name=" + s.get("name"));
        }

        // 只查询一个字段时
        List<String> lists3 = session.createQuery("select s.name from Country s", String.class)
                .setFirstResult(1)
                .setMaxResults(3)
                .list();
        for (String s : lists3) {
            System.out.println("lists3... name=" + s);
        }

        // 统一占位符
        List<Country> lists4 = session.createQuery("select c from Country c where c.start = ?1", Country.class)
                .setFirstResult(page)
                .setMaxResults(pageSize)
                .setParameter(1, country.getStart())
                .setOrder(Order.desc(Country.class, "id"))
                .list();
        for (Country s : lists4) {
            System.out.println("lists4... name=" + s.toString());
        }

        // list()---返回对象的列表 带名占位符
        List<Country> countryList = session.createQuery("select c from Country c where c.start = :start", Country.class)
                .setFirstResult(page)
                .setMaxResults(pageSize)
                .setParameter("start", country.getStart())
                .setOrder(Order.desc(Country.class, "id"))
                .list();
        Long total = session.createQuery("select count(*) from Country c", Long.class).uniqueResult();  // 总数
        System.out.println("countryList... total=" + total);
        tx.commit();

        session.close();
        return countryList;
    }

    public int save(Country country) {
        // 1. 创建SessionFactory
        Session session = sessionFactory.getCurrentSession();

        try {
            // 2. 开始一个事务
            session.beginTransaction();

            // 3. 保存实体到数据库
//            session.save(country);  //6.0开始弃用
            session.persist(country);

            // 4. 提交事务
            session.getTransaction().commit();

            // 成功后的操作，比如打印新增的实体ID
            System.out.println("New country ID: " + country.getId());

            return country.getId();

        } catch (Exception e) {
            // 5. 异常回滚及异常处理
            session.getTransaction().rollback();
            throw e;
        } finally {
            // 6. 关闭Session
            session.close();
        }
    }

    public int update(Country country) {
        Session session = sessionFactory.getCurrentSession();
        try {
            session.beginTransaction();
//            session.update(country);  //6.0开始弃用
//            session.saveOrUpdate(country);
            if (Objects.isNull(session.find(Country.class, country.getId()))) {
                session.persist(country);
            } else {
                session.merge(country);
            }
            session.getTransaction().commit();

            System.out.println("Update country ID: " + country.getId());
            return country.getId();

        } catch (Exception e) {
            session.getTransaction().rollback();
            throw e;
        } finally {
            session.close();
        }
    }

    public int remove(Country country) {
        Session session = sessionFactory.getCurrentSession();
        try {
            session.beginTransaction();
            session.remove(country);
            session.getTransaction().commit();
            return 1;
        } catch (Exception e) {
            session.getTransaction().rollback();
            throw e;
        } finally {
            session.close();
        }
    }
}
